use std::net::SocketAddr;
use tonic::{transport::Server, Request, Response, Status};
use nacos_rust_client::client::naming_client::{Instance, NamingClient};
use nacos_rust_client::client::{AuthInfo, ClientBuilder};

use infra_dict::dict_server::{Dict, DictServer};
use infra_dict::{GetDataListReq, GetDataListRes};
use infra_notice::notice_server::{Notice, NoticeServer};
use infra_notice::{SendNoticeReq, SendNoticeRes};

pub mod infra_dict {
    tonic::include_proto!("dict");
}

pub mod infra_notice {
    tonic::include_proto!("notice");
}

#[derive(Default)]
pub struct MyDict {}

#[tonic::async_trait]
impl Dict for MyDict {
    async fn get_data_list(
        &self,
        request: Request<GetDataListReq>,
    ) -> Result<Response<GetDataListRes>, Status> {
        println!("Dict服务收到请求: {:?}", request.remote_addr());
        let req = request.into_inner();
        
        let reply = GetDataListRes {
            message: format!("字典数据: {}", req.name),
        };
        Ok(Response::new(reply))
    }
}

#[derive(Default)]
pub struct MyNotice {}

#[tonic::async_trait]
impl Notice for MyNotice {
    async fn send_notice(
        &self,
        request: Request<SendNoticeReq>,
    ) -> Result<Response<SendNoticeRes>, Status> {
        println!("Notice服务收到请求: {:?}", request.remote_addr());
        let req = request.into_inner();
        
        let reply = SendNoticeRes {
            message: format!("通知已发送: {}", req.title),
        };
        Ok(Response::new(reply))
    }
}

fn register_service() -> Result<(), Box<dyn std::error::Error>> {
    // 需要添加utils依赖
    let namespace_id = "public".to_owned();
    let auth_info: Option<AuthInfo> = None;
    
    let client = ClientBuilder::new()
        .set_endpoint_addrs("152.136.130.146:8848")
        .set_auth_info(auth_info)
        .set_tenant(namespace_id)
        .set_use_grpc(true)
        .set_app_name("infra-service".to_owned())
        .build_naming_client();

    let ip = local_ipaddress::get().unwrap_or_else(|| "152.136.130.146".to_string());
    let port = 50052;
    
    // 注册字典服务
    let dict_instance = Instance::new_simple(&ip, port, "infra-dict", "DEFAULT_GROUP");
    client.register(dict_instance)?;
    
    // 注册通知服务
    let notice_instance = Instance::new_simple(&ip, port, "infra-notice", "DEFAULT_GROUP");
    client.register(notice_instance)?;
    
    println!("Infra服务已注册到Nacos: {}:{}", ip, port);
    Ok(())
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    unsafe { std::env::set_var("RUST_LOG", "INFO"); }
    env_logger::init();
    
    let addr: SocketAddr = "0.0.0.0:50052".parse().unwrap();
    
    // 注册服务到Nacos
    register_service()?;
    
    let dict_service = MyDict::default();
    let notice_service = MyNotice::default();

    println!("Infra服务器启动，监听地址: {}", addr);

    Server::builder()
        .add_service(DictServer::new(dict_service))
        .add_service(NoticeServer::new(notice_service))
        .serve(addr)
        .await?;

    Ok(())
}
